package com.lx.ngsl.core.user.service;

import java.util.List;
import java.util.Optional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.lx.ngsl.core.dto.UserInfo;
import com.lx.ngsl.core.role.service.RoleService;
import com.lx.ngsl.core.user.entity.UserEntity;
import com.lx.ngsl.core.user.repository.UserRepository;
import com.lx.ngsl.util.Md5Util;

@Service
@Transactional
public class UserService {
	@Autowired
	private UserRepository repository;
	@Autowired
	private RoleService roleService;
	@Value("${app.config.default_pwd}")
	private String defaultPwd;
	
	/**
	 * 按用户id查询用户
	 * @Title：geUserById 
	 * @param userId
	 * @return 
	 * @return ：UserEntity 
	 * @throws
	 */
	public Optional<UserEntity> geUserById(String userId) {
		
		return repository.findById(userId);
	}
	
	/*
	 * 修改用户状态
	 */
	public void changeStatus(String id) throws Exception {
		UserEntity user = repository.getOne(id);
		if(user == null) {throw new Exception("用户不存在！");}
		int status = user.getAccountState() == 1 ? 0 :1;
		user.setAccountState(status);
		repository.save(user);
	}
	
	/**
	 * 新增用户
	 * @Title：addUser 
	 * @param entity
	 * @return
	 * @return ：UserEntity 
	 * @throws
	 */
	public boolean addUser(UserEntity entity) {
		String username = entity.getUsername();
		//验证用户名是否已存在
		List<UserEntity> users = repository.findByUsername(username);
		if(users != null && users.size() > 0) {
			return false;
		}
		repository.save(entity);
		return true;
	}
	
	/*
	 * 重置密码
	 */
	public void resetPwd(String id) {
		UserEntity user = repository.getOne(id);
		user.setPassword(Md5Util.md5Str(defaultPwd, "ngsl"));
		repository.save(user);
	}
	
	/**
	 * 修改用户信息
	 * @Title：updateUser 
	 * @param entity
	 * @return
	 * @throws Exception 
	 * @return ：UserEntity 
	 * @throws
	 */
	public boolean updateUser(UserEntity entity){
		String username = entity.getUsername();
		//验证用户名是否已存在
		List<UserEntity> users = repository.findByUsername(username);
		if(users != null && users.size() > 0) {
			return false;
		}
		String id = entity.getId();
		Optional<UserEntity> user = repository.findById(id);
		if(user.isPresent()) {
			UserEntity xuser = user.get();
			xuser.setUsername(entity.getUsername());
			xuser.setRoleId(entity.getRoleId());
			repository.save(xuser);
			return true;
		}
		return false;
	}
	
	/**
	 * 保存用户实体
	 * @Title：save 
	 * @param ：@param user
	 * @param ：@return 
	 * @return ：boolean 
	 * @throws
	 */
	public boolean save(UserEntity user) {
		UserEntity u = repository.save(user);
		if(u == null)
			return false;
		else
			return true;
	}
	
	/**
	 * 根据用户id删除用户信息
	 * @Title：deleteUser 
	 * @param id
	 * @throws Exception 
	 * @return ：void 
	 * @throws
	 */
	public void deleteUser(String id){
		repository.deleteById(id);
	}
	
	/**
	 * 根据用户id查询用户信息
	 * @Title：getUser 
	 * @param id
	 * @return
	 * @throws Exception 
	 * @return ：UserEntity 
	 * @throws
	 */
	public Optional<UserEntity> getUser(String id) throws Exception {

		return repository.findById(id);
	}
	
	/**
	 * 将用户实体对象转化为用户信息类对象
	 * @Title：toUserInfo 
	 * @param ：@param user
	 * @param ：@return 
	 * @return ：UserInfo 
	 * @throws
	 */
	public UserInfo toUserInfo(UserEntity user) {
		UserInfo userInfo = new UserInfo();
		userInfo.setAccount(user.getAccount());
		userInfo.setOrgId(user.getOrgId());
		userInfo.setPhone(user.getPhone());
		String roleId = user.getRoleId();
		userInfo.setRole(roleService.getRole(roleId));
		userInfo.setUserId(user.getId());
		userInfo.setName(user.getUsername());
		return userInfo;
		
	}
	
	/**
	 * 按账户和密码查询用户
	 * @Title：getUserByCountAndPwd 
	 * @param username
	 * @param password
	 * @return 
	 * @return ：UserEntity 
	 * @throws
	 */
	public UserEntity getUserByCountAndPwd(String username,String password) {
		
		
		return repository.findByAccountAndPassword(username, password);
	}
	
	
	/**
	 * 根据用户名（账号）、用户姓名、用户id分页查询用户信息
	 * @Title：listUser 
	 * @param username
	 * @param name
	 * @param orgId
	 * @param pageable
	 * @return 
	 * @return ：Page<UserEntity> 
	 * @throws
	 */
	public Page<UserEntity> listUser(String username, String name,String orgId, Pageable pageable) throws Exception {
		Page<UserEntity> list = userListPage(username,name,orgId,pageable);
		return list;
	}
	
	/**
	 * 根据用户名（账号）、用户姓名、用户id分页查询用户信息
	 * @Title：userListPage 
	 * @param username
	 * @param name
	 * @param orgId
	 * @param pageable
	 * @return 
	 * @return ：Page<UserEntity> 
	 * @throws
	 */
	public Page<UserEntity> userListPage(String username, String name,String orgId, Pageable pageable) throws Exception {
		
		Page<UserEntity> list = repository.findAll(new Specification<UserEntity>() {
			@Override
			public Predicate toPredicate(Root<UserEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate predicate = cb.conjunction();
				List<Expression<Boolean>> expressions = predicate.getExpressions();
				if (!StringUtils.isEmpty(username)) {
					expressions.add(cb.like(root.<String> get("username"), "%" + username + "%"));
				}
				if (!StringUtils.isEmpty(name)) {
					expressions.add(cb.like(root.<String> get("username"), "%" + name + "%"));
				}
				if (!StringUtils.isEmpty(orgId)) {
					expressions.add(cb.equal(root.<String> get("orgId"), orgId));
				}
				return predicate;
			}
		}, pageable);

		return list;
	}
	
	/**
	 * 更改密码
	 * @Title：changePwd 
	 * @param userId
	 * @param pwd
	 * @throws Exception 
	 * @return ：void 
	 * @throws
	 */
	public boolean changePwd(String userId, String pwd){
		pwd = Md5Util.md5Str(pwd, "ngsl");
		int n = repository.changePwd(userId, pwd);
		if(n == 0) {
			return false;
		}else {
			return true;
		}
	}
	
	/**
	 * 锁定用户
	 * @Title：lockUser 
	 * @param userId
	 * @throws Exception 
	 * @return ：void 
	 * @throws
	 */
	public void lockUser(String userId) throws Exception {

		repository.lockUser(userId);
	}
	
	/**
	 * 解锁用户
	 * @Title：unlockUser 
	 * @param userId
	 * @throws Exception 
	 * @return ：void 
	 * @throws
	 */
	public void unlockUser(String userId) throws Exception {

		repository.unlockUser(userId);
	}
	
	
	/*
	 * 判断用户名是否重复
	 */
	public boolean isUserExist(String username) {
		List<UserEntity> user = repository.findByUsername(username);
		if(user == null || user.size() == 0) {
			return false;
		}
		return true;
	}
	
	public boolean authenticated(String token) {
		UserEntity user = null;
		try {
			user = repository.findByToken(token);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		if(user == null) {
			return false;
		}else {
			return true;
		}
	}
	
}
